#include "StdAfx.h"
#include "GuiHandler.h"
#include "Client.h"

GuiHandler::GuiHandler(int w, int h, Client* c)
{
	lines = new MyArray<string>();
	userList = new MyArray<string>();
	width = w;
	height = h;
	client = c;
	leftColumbWidth = 14;
	x = 1;
	y = 1;
	paint();
	start();
}

GuiHandler::~GuiHandler(void)
{
	delete lines;
}

void GuiHandler::gotoxy(short x, short y)
{  
	COORD coord = {x, y};
	SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ), coord );
}

void GuiHandler::paint() {
	string c = "*";
	DWORD dwExitCode;
	wstring w = stringToWideString(c);
	LPCWSTR result = w.c_str();
	for(int i = 0; i<height; i++) {

		//Print horizontal lines
		if(i==0) {
			for(int j=1; j<width; j++) {
				COORD coord2 = {j,i};
				WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
			}
		} else if(i == height-3) {
			for(int j=1; j<width; j++) {
				COORD coord2 = {j,i};
				WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
			}
		}
		else if(i == height-1) {
			for(int j=1; j<width; j++) {
				COORD coord2 = {j,i};
				WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
			}
		}

		//print vertical line
		COORD coord2 = {0,i};
		WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);

		COORD coord3 = {width,i};
		WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord3,&dwExitCode);
		if(i< height-3) {
			COORD coord3 = {width - leftColumbWidth,i};
			WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord3,&dwExitCode);
		}
	}
	if(lines->size() > 0) {
		int thisY = height-4;
		int linesPrinted = 0;
		for(int j=lines->size(); j>0; j --) {
			COORD coord = {x,thisY};
			DWORD dwExitCode;

			string s = lines->get(j-1);
			wstring w = stringToWideString(s);
			LPCWSTR result = w.c_str();

			clearLine(x,thisY,width - leftColumbWidth - 2);

			WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord,&dwExitCode);
			linesPrinted ++;
			thisY--;
			if(linesPrinted == 20) {
				break;
			}
		}
	}

	if(userList->size() > 0) {
		for(int y=1;y<height-3;y++) {
			clearLine(66,y,12);
		}
		for(int y2=0;y2<userList->size();y2++) {
			string u = userList->get(y2);
			if(u.length() > 12) {
				u = u.substr(0,12);
			}
			COORD coord2 = {width - leftColumbWidth+1,y2+1};
			DWORD dwExitCode;
			string s = u;
			wstring w = stringToWideString(s);
			LPCWSTR result = w.c_str();
			WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
		}
	}
}

void GuiHandler::start() {
	CreateThread(0,0,run,this,0,NULL);
}

void GuiHandler::myPrint(string c) {
	int i = c.length();
	while(i > width - leftColumbWidth - 1) {
		string temp = c.substr(0,width - leftColumbWidth - 2);
		lines->add(temp);
		string restMessage = " ";
		for(int i = 1; i<client->getName().length() + 3;i++) {
			restMessage.append(" ");
		}
		restMessage += c.substr(width - leftColumbWidth - 2);
		c = restMessage;
		i = c.length();
	}
	lines->add(c);
	int thisY = height-4;
	int linesPrinted = 0;
	for(int j=lines->size(); j>0; j --) {
		COORD coord = {x,thisY};
		DWORD dwExitCode;

		string s = lines->get(j-1);
		wstring w = stringToWideString(s);
		LPCWSTR result = w.c_str();

		clearLine(x,thisY,width - leftColumbWidth - 2);

		WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord,&dwExitCode);
		linesPrinted ++;
		thisY--;
		if(linesPrinted == 20) {
			break;
		}
	}
}

void GuiHandler::printUserList(string s) {
	userList->clear();
	string userList2 = s.substr(2);
	int index = userList2.find_first_of(',');
	while(index > 0) {
		string user = userList2.substr(0,index);
		userList->add(user);
		userList2 = userList2.substr(index+1);
		index = userList2.find_first_of(',');	
	}

	for(int y=1;y<height-3;y++) {
		clearLine(66,y,12);
	}
	for(int y2=0;y2<userList->size();y2++) {
		string u = userList->get(y2);
		if(u.length() > 12) {
			u = u.substr(0,12);
		}
		COORD coord2 = {width - leftColumbWidth+1,y2+1};
		DWORD dwExitCode;
		string s = u;
		wstring w = stringToWideString(s);
		LPCWSTR result = w.c_str();
		WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
		
	}
}

string GuiHandler::readInput() {
	char recMessage[256];
	string message;
	while(true) {
		gotoxy(1,22);
		cout << "[" << client->getName() << "]: ";
		cin.getline( recMessage, 256, '\n' );

		string s(recMessage);
		string totalM = "[" + client->getName() + "] " + s;
		clearLine(client->getName().length() + 4,22,78 - (client->getName().length() + 4));
		return s;
	}
	return "";
}

void GuiHandler::clearLine(int x, int y, int length) {
	string c = " ";
	for(int i=0; i<length; i++) {
		c.append(" ");
	}
	DWORD dwExitCode;
	wstring w = stringToWideString(c);
	LPCWSTR result = w.c_str();

	COORD coord2 = {x,y};			
	WriteConsoleOutputCharacter(GetStdHandle ( STD_OUTPUT_HANDLE ),result,w.length(),coord2,&dwExitCode);
}

unsigned long _stdcall GuiHandler::run(void * param) {
	GuiHandler* This = (GuiHandler*)param;
	while(true) {
		string s = This->readInput();
		if(s.length() > This->width-2) {
			system("cls");
			This->paint();
		}
		This->client->SendData(s);
	}
}

wstring GuiHandler::stringToWideString(const string& s)
{
	int len;
	int slength = (int)s.length() + 1;
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
	wchar_t* buf = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
	std::wstring r(buf);
	delete[] buf;
	return r;
}


